package com.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.pojo.ChatBean;
import com.service.ChatService;
import com.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author:TTW
 * @Discription:websocket服务
 */
@ServerEndpoint("/websocket/{name}/{usertype}/{uname}/{areaId}")
@RestController
public class WebSocketServer {

//    @Autowired
//    private HttpServletRequest request;

    public static ChatService chatService;
    //存储客户端的用户连接对象,每个用户的客户端连接都会产生一个连接对象
    private static ConcurrentHashMap<String, WebSocketServer> map = new ConcurrentHashMap();
    //存储客户端的客服连接对象,每个客服的客户端连接都会产生一个连接对象
    public static ConcurrentHashMap<String, WebSocketServer> kefumap = new ConcurrentHashMap();
    //客服对应的区域id
    public static ConcurrentHashMap<String, String> areaMap = new ConcurrentHashMap();
    //定义一个map用来存储客服的聊天数量（人数）
    public static Map<String, Integer> chatmap = new HashMap<String, Integer>();
    //定义一个map建立用户正在聊天的客服名：key为用户名，value为客服名，因为key不能重复
    private static Map<String, String> kefuAndUser = new HashMap<>();
    //每个连接都会有自己的会话
    private Session session;
    private String name;


    /**
     * 建立websocket连接
     * @param name userid 一般是手机号 例如：+86133****0750
     * @param usertype user1表示用户连接 user2表示客服连接
     * @param uname 用户名，注册时的名字
     * @param session
     * @throws IOException
     */
    @OnOpen
    public void open(@PathParam("name") String name, @PathParam("usertype") String usertype, @PathParam("uname") String uname,@PathParam("areaId") String areaId, Session session) throws IOException {
        if (usertype.equals("user1")) {
            System.out.println("用户："+name+"连接了，区域="+areaId);
            System.out.println("用户数量："+map.size()+",客服数："+kefumap.size()+",chatmap="+chatmap.size());
            String kefuname = ""; //为用户匹配的客服名

            map.put(name, this);
            this.session = session;
            this.name = name;
            int minkefu = 0;      //为用户匹配客服，找到聊天数量最少的那个客服，
            Set<Map.Entry<String, Integer>> enchat = chatmap.entrySet();
            for (Map.Entry<String, Integer> entry : enchat) {
                int ab = entry.getValue();
                String area = areaMap.get(entry.getKey());
                System.out.println("该客服的区域"+area);
                System.out.println(areaId);
                System.out.println("ab=="+ab);
                System.out.println("minkefu=="+minkefu);
                if (areaId.equals(areaMap.get(entry.getKey()))) {
                    if (ab<=minkefu){
                        kefuname = entry.getKey();
                        minkefu = ab;
                    }else if (minkefu==0){
                        kefuname = entry.getKey();
                        minkefu = ab;
                    }

                }
            }

            JSONObject jsonObject = new JSONObject();//jsonObject是发送的消息内容：type=1表示第一次连接给用户发的，type=2才是聊天时发的消息，message是具体的发送内容 type==3表示没有客服在线
            JSONObject kefujson = new JSONObject();//kefujson是发送给客服的消息内容：type=1表示客服要增加一个选项卡，type=2才是聊天时发的消息，message是具体的发送内容 type==3表示没有用户已下线
            if (!kefuname.equals("")) {
                chatmap.put(kefuname,minkefu+1);//建立关系之后要给客服对应的聊天人数+1
                String ss = chatService.addChat(kefuname, name);//数据库建立客服与用户的关系
                if (ss == null) {
//                    for (Map.Entry<String, Integer> entry : enchat) {
//                        String names = entry.getKey();
//                        int ab = entry.getValue();
//                        if (kefuname.equals(names)) {
//                            entry.setValue(ab + 1);
//                        }
//                    }
                    jsonObject.put("message", kefuname);
                    jsonObject.put("type", 1);
                    jsonObject.put("sendname", name);
                    jsonObject.put("kname",kefuname);
                    String js = "{\"type\":2,\"name\":\"" + kefuname + "\",\"kefu\":\"" + name + "\",\"msg\":" + jsonObject + "}";
                    getMessage(js);//给用户发消息
                    kefujson.put("message", name);
                    kefujson.put("type", 1);
                    kefujson.put("sendname", name);
                    kefujson.put("uname",uname);
                    String kefujs = "{\"type\":1,\"name\":\"" + name + "\",\"kefu\":\"" + kefuname + "\",\"msg\":" + kefujson + "}";
                    getMessage(kefujs);//给客服发消息
                    //通过kefuAndUser建立聊天关系
                    kefuAndUser.put(name, kefuname);
//                    chatService.iAmKefu(kefuname,name);
                } else {
                    jsonObject.put("message", "连接失败！请重新打开");
                    jsonObject.put("type", 3);
                    jsonObject.put("sendname", name);
                    jsonObject.put("kname",kefuname);
                    String js = "{\"type\":2,\"name\":\"" + kefuname + "\",\"kefu\":\"" + name + "\",\"msg\":" + jsonObject + "}";
                    getMessage(js);//给用户发消息
                }
            } else {
                jsonObject.put("message", "该区域没有客服在线");
                jsonObject.put("type", 3);
                jsonObject.put("sendname", kefuname);
                String js = "{\"type\":2,\"name\":\"" + kefuname + "\",\"kefu\":\"" + name + "\",\"msg\":" + jsonObject + "}";
                getMessage(js);
            }
        } else if (usertype.equals("user2")) {
            System.out.println("客服"+name+"连接了");
            System.out.println("用户数量："+map.size()+",客服数："+kefumap.size()+",chatmap="+chatmap.size());
            System.out.println("客服所属区域"+areaId);
//            Set<Map.Entry<String, WebSocketServer>> entries2 = kefumap.entrySet();
//            for (Map.Entry<String, WebSocketServer> entry : entries2) {//如果该客服已经连接了，就不加入kefumap
//                String names = entry.getKey();
//                if (name.equals(names)) {
//                    kefumap.put(name,this);
//                    this.session = session;//重新连接也要设置session和name，不然断开连接会报错，name为null
//                    this.name = name;
//                    entry.setValue(this);
//                    chatmap.put(name, 0);
//                    return;
//                }
//            }
//            System.out.println(this.toString());
            if(name!=null){
                kefumap.put(name, this);
                areaMap.put(name, areaId);
                this.session = session;
                this.name = name;
                chatmap.put(name, 0);
            }else{

            }
        }
//        request.getSession().setAttribute("map", map);
//        request.getSession().setAttribute("kefumap", kefumap);
//        request.getSession().setAttribute("chatmap", chatmap);
//        request.getSession().setAttribute("kefuAndUser", kefuAndUser);

        System.out.println("连接之后---------");
        System.out.println("用户数量："+map.size()+",客服数："+kefumap.size()+",chatmap="+chatmap.size());
    }

    @OnClose
    public void close() throws IOException {
//        ConcurrentHashMap<String, WebSocketServer> map = (ConcurrentHashMap<String, WebSocketServer>) request.getSession().getAttribute("map");
//        ConcurrentHashMap<String, WebSocketServer> kefumap = (ConcurrentHashMap<String, WebSocketServer>) request.getSession().getAttribute("kefumap");
//        Map<String, Integer> chatmap = (Map<String, Integer>) request.getSession().getAttribute("chatmap");
//        Map<String, String> kefuAndUser = (Map<String, String>) request.getSession().getAttribute("kefuAndUser");
        WebSocketServer userClose = map.remove(name);
        WebSocketServer kefuClose = kefumap.remove(name);
        System.out.println("有人断开连接了");
        if (userClose != null) {//一个用户断开了连接，
            System.out.println("用户:"+name+"-断开连接了");
//            for (Map.Entry<String, String> entry : kefuAndUser.entrySet()) {
//                if (entry.getKey().equals(name)) {
//                    JSONObject kefujson = new JSONObject();//kefujson是发送给客服的消息内容：type==5表示对方断开了连接
//                    kefujson.put("message", name);
//                    kefujson.put("type", 5);
//                    kefujson.put("sendname", name);
//                    String kefujs = "{\"type\":1,\"name\":\"" + name + "\",\"kefu\":\"" + entry.getValue() + "\",\"msg\":" + kefujson + "}";
//                    getMessage(kefujs);
//                    break;
//                }
//            }
            kefuAndUser.remove(name);   //删除用户和客服正在聊天的关系
        }
        if (kefuClose != null) {//一个客服断开了连接
            System.out.println("客服："+name+"断开连接了");
            areaMap.remove(name);
            for (Map.Entry<String, String> entry : kefuAndUser.entrySet()) {
                if (entry.getValue().equals(name)) {
                     JSONObject userjson = new JSONObject();//userjson是发送给用户的消息内容：type==5表示对方断开了连接
                    userjson.put("message", name);
                    userjson.put("type", 5);
                    userjson.put("sendname", name);
                    String js = "{\"type\":2,\"name\":\"" + name + "\",\"kefu\":\"" + entry.getKey() + "\",\"msg\":" + userjson + "}";
                    getMessage(js);//给用户发消息
                }
            }
            chatmap.remove(name);
        }
//        System.out.println("用户数量："+getConnetNum()+",客服数："+getConnetNumKefu()+",chatmap="+getChatMapSize());
//        request.getSession().setAttribute("map", map);
//        request.getSession().setAttribute("kefumap", kefumap);
//        request.getSession().setAttribute("chatmap", chatmap);
//        request.getSession().setAttribute("kefuAndUser", kefuAndUser);
    }

    @OnError
    public void error(Throwable error) {
        error.printStackTrace();
    }

    @OnMessage
    public void getMessage(String message) throws IOException {
        if ("ping".equals(message)){
            System.out.println(this.toString()+"  ping");
            this.send("ping");
        }else{
//            ConcurrentHashMap<String, WebSocketServer> map = (ConcurrentHashMap<String, WebSocketServer>) request.getSession().getAttribute("map");
//            ConcurrentHashMap<String, WebSocketServer> kefumap = (ConcurrentHashMap<String, WebSocketServer>) request.getSession().getAttribute("kefumap");
            Set<Map.Entry<String, WebSocketServer>> entries = map.entrySet();    //用户的连接
            Set<Map.Entry<String, WebSocketServer>> entries2 = kefumap.entrySet();  //客服的连接
            ChatBean chatBean = JSON.parseObject(message, ChatBean.class);
            JSONObject obj = JSONObject.parseObject(chatBean.getMsg());
            String ss = "";
            if ((int) obj.get("type") == 10){

                Set<Map.Entry<String, Integer>> enchat = chatmap.entrySet();
                String areaId = chatBean.getKefu();
                String kefuname = ""; //为用户匹配的客服名
                int minkefu = 0;      //为用户匹配客服，找到聊天数量最少的那个客服，
                //查看是否有该区域的客服在线
                for (Map.Entry<String, Integer> entry : enchat) {
                    int ab = entry.getValue();
                    if (areaId.equals(areaMap.get(entry.getKey()))) {
                        if (ab<=minkefu){
                            kefuname = entry.getKey();
                            minkefu = ab;
                        }else if (minkefu==0){
                            kefuname = entry.getKey();
                            minkefu = ab;
                        }
                    }
                }
                if (StringUtil.isNull(kefuname)){//当没有客服在线时，将消息存在数据库，
                    String str = chatService.addMessageWhenNotKefu(chatBean.getName(), String.valueOf(obj.get("message")),chatBean.getPtype(),areaId);
                    if (str ==null){
                        str="没有客服在线";
                        for (Map.Entry<String, WebSocketServer> entry : entries) {
                            if (entry.getKey().equals(name)) {
                                entry.getValue().send("{\"message\":\""+str+"\",\"type\":3}");
                                break;
                            }
                        }
                    }
                }else{//如果匹配到客服就重新给客服和用户同时发消息
                    chatService.addChatDetail(name,kefuname,obj.get("message"),1,chatBean.getPtype());//存消息入数据库
                    for (Map.Entry<String, WebSocketServer> entry : entries) {
                        if (entry.getKey().equals(name)) {
                            entry.getValue().send("{\"message\":\""+kefuname+"\",\"type\":6}");//数字6：用户端重新给kefu赋值
                            break;
                        }
                    }
                    for (Map.Entry<String, WebSocketServer> entry : entries2) {
                        if (entry.getKey().equals(kefuname)) {
                            entry.getValue().send("{\"message\":\""+name+"\",\"type\":1}");
                            break;
                        }
                    }
                }
            } else{//type==2:正常消息 type==10:用户找不到客服的消息
                if ((int) obj.get("type") == 2) {
                    ss = chatService.addChatDetail(name, chatBean.getKefu(), obj.get("message"), chatBean.getType(),chatBean.getPtype());//将聊天记录存入数据库
                }
                if (ss == null || ss == "") {
                    if (chatBean.getType() == 1) {//用户给客服发送消息
                        if (entries2.isEmpty()) {//没有客服在线，给用户发给消息说明情况
                            for (Map.Entry<String, WebSocketServer> entry : entries) {
                                if (entry.getKey().equals(name)) {
                                    entry.getValue().send("{\"message\":\"当前没有客服在线哦！\",\"type\":3}");
                                    break;
                                }
                            }
                        } else {
                            int kefusize = 0;         //用于循环客服,判断接收消息的客服是否在线
                            for (Map.Entry<String, WebSocketServer> entry : entries2) {
                                if (entry.getKey().equals(chatBean.getKefu())) {
//                                System.out.println("接收消息的客服"+entry.getValue().toString());
                                    entry.getValue().send(chatBean.getMsg());
                                    break;
                                }
                                kefusize++;
                            }
                            if (kefusize == entries2.size()) {//这个客服不在线
                                for (Map.Entry<String, WebSocketServer> entry : entries) {
                                    if (entry.getKey().equals(name)) {
                                        entry.getValue().send("{\"message\":\"该客服下线了，请重新打开聊天\",\"type\":3}");
                                        break;
                                    }
                                }
                            }
                        }
                    } else if (chatBean.getType() == 2) {           //客服给用户发送消息
                        for (Map.Entry<String, WebSocketServer> entry : entries) {
                            if (entry.getKey().equals(chatBean.getKefu())) {
                                entry.getValue().send(chatBean.getMsg());
                                return;
                            }
                        }
                        System.out.println("发送失败");
                        //发送失败了给客服发消息--错误提示
                        for (Map.Entry<String, WebSocketServer> entry : entries2) {
                            if (entry.getKey().equals(name)) {
//                            System.out.println("接收消息的客服"+entry.getValue());
                                entry.getValue().send("{\"message\":\""+ss+"\",\"type\":6,\"name\":\""+chatBean.getKefu()+"\"}");/// 6代表对方处于离线状态
                                break;
                            }
                        }
                    }
                } else {
                    if (chatBean.getType()==1){//给用户发错误提示
                        for (Map.Entry<String, WebSocketServer> entry : entries) {
                            if (entry.getKey().equals(name)) {
//                            System.out.println("接收消息的用户"+entry.getValue());
                                entry.getValue().send("{\"message\":\""+ss+"\",\"type\":4}");
                                break;
                            }
                        }
                    }else if (chatBean.getType()==2){//给客服发错误提示
                        for (Map.Entry<String, WebSocketServer> entry : entries2) {
                            if (entry.getKey().equals(name)) {
//                            System.out.println("接收消息的客服"+entry.getValue());
                                entry.getValue().send("{\"message\":\""+ss+"\",\"type\":4}");
                                break;
                            }
                        }
                    }
                }

            }
        }


    }

    public void send(String message) throws IOException {
        if (session.isOpen()) {
            session.getBasicRemote().sendText(message);
        }
    }

//    public int getConnetNum() {
//        return map.size();
//    }

//    public int getConnetNumKefu() {
//        return kefumap.size();
//    }

//    public int getChatMapSize(){
//        return chatmap.size();
//    }

//    /**
//     * 获取客服的聊天人数
//     * @param kefuname 客服名
//     * @return
//     */
//    public int getKefuChatSize(String kefuname){
//        int size = 0;  //人数
//        for (Map.Entry<String, String> entry : kefuAndUser.entrySet()) {
//            if (entry.getValue().equals(kefuname)) {
//                size++;
//            }
//        }
//        return size;
//    }
}

